package com.dmp.common;

import com.dmp.common.redis.JedisUtils;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.sql.*;
import java.util.*;

/**
 * 
 * @author 胡涛
 * @Description:加载ehcache-config.xml文件、jdbc配置文件
 * @date 2015年11月5日下午1:13:15
 */
public class LoadFile {
	private final static Logger log = LoggerFactory.getLogger(LoadFile.class);
	public static CacheManager manager = CacheManager.create();
	public static Properties props = new Properties();
	public static LoadFile loadFile;
	public static List<Map<String, String>> list = new ArrayList<Map<String, String>>();

	public LoadFile() {
		try {
			props.load(this.getClass().getClassLoader().getResourceAsStream("dpi4g.properties"));
			String ehcacheReload = props.getProperty("ehcacheReload");
			if (null == loadFile || ehcacheReload.toLowerCase().equals("true")) {
				manager.clearAll();
				dealProcess();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage());
		}
	}

	public void dealProcess() {
		Connection connection = null;
		PreparedStatement psmt = null;
		ResultSet ret = null;
		try {

			connection = DriverManager.getConnection(props.getProperty("dburl"), props.getProperty("dbuser"),
					props.getProperty("dbpwd"));
			SAXReader reader = new SAXReader();
			Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream("ehcache-config.xml"));
			Element root = document.getRootElement();
			Element nodeElement = root.element("table");
			List nodes = root.elements("table");
			for (Iterator it = nodes.iterator(); it.hasNext();) {
				Element elm = (Element) it.next();
				String tableName = elm.attributeValue("name").trim().toLowerCase();
				Cache cachae = manager.getCache(tableName);
				if (null == cachae) {
					manager.addCache(tableName); // 加入缓存，以表的名字作为key
				}
				dealAllData(tableName,connection);
				List properties = elm.elements("propertity");
				for (Iterator its = properties.iterator(); its.hasNext();) {
					Element pro = (Element) its.next();
					// Map<String,String> map=new HashMap<String,String>();
					Class clazz =null;
					String inputKeys = pro.attributeValue("inputKeys");
					String outputKeys = pro.attributeValue("outputKeys");
					String resultType = pro.attributeValue("resultType");
					String orderBy = pro.attributeValue("orderBy");
					boolean resultTypeDefault = false;
					if (null == resultType) {
						resultTypeDefault = true;
					}else{
						 clazz = Class.forName(resultType);
					}
					if (null == orderBy) {
						orderBy = "";
					}
					String id = pro.attributeValue("id");
					if (null == id || null == inputKeys || null == outputKeys) {
						continue;
					}
					inputKeys = inputKeys.trim().toLowerCase();
					id = id.trim().toLowerCase();
					if (inputKeys.endsWith(",")) {
						inputKeys = inputKeys.substring(0, inputKeys.length() - 1);
					}
					if (outputKeys.endsWith(",")) {
						outputKeys = outputKeys.substring(0, outputKeys.length() - 1);
					}
					String querySql = "select * from " + tableName;
					if (!"".equals(orderBy))
						querySql += " order by " + orderBy;
					if (null != connection) {
						psmt = connection.prepareStatement(querySql);
						ret = psmt.executeQuery();

						String[] resultColumns = outputKeys.split(",");
						String[] inputColumns = inputKeys.split(",");
						if (resultTypeDefault || (null!=clazz&&clazz.isAssignableFrom(String.class))) {
							//字符串
							dealTyteOfString(tableName, id, inputColumns, resultColumns, ret);
						}else{
							//其他处理
							if (clazz.isAssignableFrom(List.class)) {
								dealTypeOfList(tableName, id, inputColumns, resultColumns, ret);
							}

							
						}
					
					}
				}
			}

		} catch (Exception e) {
			log.error(e.getMessage());
		}
	}

	/**
	 * @Description：将全表数据放入缓存
	 * @param tableName
	 * @param connection
	 * @throws Exception
	 */
	public void dealAllData(String tableName,Connection connection) throws Exception{
		List<Object> allColoumnList = new ArrayList<Object>();// 列的所有数据
		String querySql = "select * from " + tableName;
		PreparedStatement psmt	 = connection.prepareStatement(querySql);
		ResultSet ret = psmt.executeQuery();
		while (ret.next()) {
			ResultSetMetaData data = ret.getMetaData();
			Map<String, Object> map = new HashMap<String, Object>();
			for (int i = 1; i <= data.getColumnCount(); i++) {
				// 获得所有列的数目及实际列数
				String columnName = data.getColumnName(i);
				map.put(columnName, null==ret.getObject(columnName)?"":ret.getObject(columnName));
				}
			allColoumnList.add(map);
		}
		if(allColoumnList.size()>0){
			String key = tableName + "_all";
			Cache cache = manager.getCache(tableName);
			net.sf.ehcache.Element element = new net.sf.ehcache.Element(key, allColoumnList);
			cache.put(element);
			boolean isExists = JedisUtils.exists(key);
			if (isExists) {
				JedisUtils.del(key);
			}
//			JedisUtils.setObjectList(key, allColoumnList, 0);
			List<Object> ll=new ArrayList();
			for(int m=0;m<100;m++){
				ll.add("mmm"+m+100);
			}
			JedisUtils.setObjectList(key, ll, 0);
		}
	}
	public Properties loadProperties() {
		Properties props = new Properties();
		try {
			props.load(this.getClass().getClassLoader().getResourceAsStream("dpi4g.properties"));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage());
		}
		return props;
	}
	
	public void increamentDataByKey(String tableName,String id,String val){
		String[] result;
		try {
			result = findInputKeys(tableName,id);
			String inputkeys=result[0],oupputkeys=result[1],resultType=result[2];
			String[] condition=val.split(",");
			String[] inputColumns=inputkeys.split(",");
			String whereStr="";
			for(int i=0;i<inputColumns.length;i++){
				whereStr+=" and "+inputColumns[i]+"="+condition[i];
			}
			String sql="select "+inputkeys+","+oupputkeys+" from "+tableName+" where 1=1" +whereStr;
			Connection connection = null;
			PreparedStatement psmt = null;
			ResultSet ret = null;
			String[] resultColumns = oupputkeys.split(",");
			try {
				connection = DriverManager.getConnection(props.getProperty("dburl"), props.getProperty("dbuser"),props.getProperty("dbpwd"));
				psmt = connection.prepareStatement(sql);
				ret = psmt.executeQuery();
				if (null == resultType) {
						//字符串
					dealTyteOfString(tableName, id, inputColumns, resultColumns, ret);
				}else{
					Class clazz=Class.forName(resultType);
					if (clazz.isAssignableFrom(String.class)) {
						dealTyteOfString(tableName, id, inputColumns, resultColumns, ret);
					}
					if (clazz.isAssignableFrom(List.class)) {
						dealTypeOfList(tableName, id, inputColumns, resultColumns, ret);
					}
					
				}
			}catch(Exception e){
				
			}


	
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage());
		}
		
	}
	/**
	 * @Description：根据表名称,id获取输入条件
	 * @param tableName
	 * @param id
	 * @return
	 * @throws Exception 
	 */
	public String[] findInputKeys(String tableName,String id) throws Exception{
		String[] result=new String[]{"","",""} ;
		SAXReader reader = new SAXReader();
		Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream("ehcache-config.xml"));
		Element root = document.getRootElement();
		Element nodeElement = root.element("table");
		List nodes = root.elements("table");
		for (Iterator it = nodes.iterator(); it.hasNext();) {
			Element elm = (Element) it.next();
			String name = elm.attributeValue("name").trim().toLowerCase();
			if(name.equals(tableName)){
				List properties = elm.elements("propertity");
				for (Iterator its = properties.iterator(); its.hasNext();) {
					Element pro = (Element) its.next();
					// Map<String,String> map=new HashMap<String,String>();
					String tempid = pro.attributeValue("id");
					tempid = tempid.trim().toLowerCase();
					if(tempid.equals(id)){
						String inputKeys = pro.attributeValue("inputKeys");
						inputKeys = inputKeys.trim().toLowerCase();
						if (inputKeys.endsWith(",")) {
							result[0] = inputKeys.substring(0, inputKeys.length() - 1);
						}else{
							result[0]=inputKeys;
						}
					}
					String outputKeys = pro.attributeValue("outputKeys");
					outputKeys = outputKeys.trim().toLowerCase();
					if(outputKeys.endsWith(",")){
						result[1] = outputKeys.substring(0, outputKeys.length() - 1);
					}else{
						result[1] = outputKeys;
					}
					result[2]  = pro.attributeValue("resultType");
					break;
				}
				break;
			}
		}
		return result;
	}
	
	public void dealTypeOfList(String tableName,String id,String[]inputColumns,String[]resultColumns, ResultSet ret ){
		Map<String,Object> globalMap=new HashMap<String,Object>();
		List<Object> list = new ArrayList<Object>();
		// 返回列表
		try{
			while (ret.next()) {
				String globalKey = "";
				String keyStr="";
				for (String col : inputColumns) {
					keyStr += ret.getString(col.trim().toLowerCase()) + "_";
				}
				if (!keyStr.equals("")) {
					keyStr = keyStr.substring(0, keyStr.length() - 1);
				}
				// 判断inputKey是否是空，如果是空，
				globalKey = tableName + "_" + id + "_"+ keyStr.trim();
				Map<String,Object> map=new HashMap<String,Object>();
				for (String column : resultColumns) {
					String key = column.trim().toLowerCase();
					map.put(key, ret.getObject(key));
				}
				List<Map<String,Object>> initlist;
				if(!globalMap.containsKey(globalKey)){
					initlist=new   ArrayList<Map<String,Object>>();
					initlist.add(map);
					globalMap.put(globalKey, initlist);
				}else{
					initlist=(List<Map<String,Object>>)globalMap.get(globalKey);
					initlist.add(map);
					globalMap.put(globalKey, initlist);
				}
			}
			for (Iterator i = globalMap.keySet().iterator(); i.hasNext();) {
			    Object obj = i.next();
			    String key = obj.toString();
//			    List<Object> localList = ( List<Object>)globalMap.get(obj);
			    List<Map<String,Object>> localList = ( List<Map<String,Object>>)globalMap.get(obj);
			    Cache cache = manager.getCache(tableName);
				net.sf.ehcache.Element element = new net.sf.ehcache.Element(key, localList);
				cache.put(element);
			   }

		}catch(Exception e){
			
		}
		

	}
	
	public void dealTyteOfString(String tableName,String id,String[]inputColumns,String[]resultColumns, ResultSet ret ){
		try{
			while (ret.next()) {
				String resultStr = "", keyStr = "";
					for (String col : inputColumns) {
						keyStr += ret.getObject(col.trim().toLowerCase()).toString() + "_";
					}
					if (!keyStr.equals("")) {
						keyStr = keyStr.substring(0, keyStr.length() - 1);
					}
					for (String column : resultColumns) {
						resultStr += ret.getString(column.trim().toLowerCase()) + ",";
					}
					if (!resultStr.equals("")) {
						resultStr = resultStr.substring(0, resultStr.length() - 1);
					}
				
					Cache cache = manager.getCache(tableName);
					String cache_key = tableName + "_" + id + "_" + keyStr;
					net.sf.ehcache.Element element = new net.sf.ehcache.Element(cache_key, resultStr);
					cache.put(element);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
}
